#-*-coding:utf-8-*-

'''
# ----------------------------------------------------------------------------
#  Purpose:     生成数据可视化图表

#  Author:      青衫少年春归也

#  Created:     2020.03.29

# ----------------------------------------------------------------------------
'''

import os
import logging
from pathlib import Path
import pyecharts.options as opts
from pyecharts.charts import Line
from snapshot_selenium import snapshot
from pyecharts.globals import ThemeType
from pyecharts.render import make_snapshot

logger = logging.getLogger(__name__)


class EchartLine():
    def __init__(self, width:str='960px', height:str='540px', theme_name:str='DARK'):
        """
        初始化 折线图 对象
            :params width:图表宽度
            :params height:图表高度
            :params background_color:背景颜色
            :params area_color:区域颜色
        """
        self.files_path = []
        theme = getattr(ThemeType, theme_name) or ThemeType.DARK
        self.line = Line(init_opts=opts.InitOpts(width=width,
                                                 height=height,
                                                 theme=theme
                                                ))

    def set_x_xis(self, x_data:list):
        """
        添加X轴数据，并配置X轴显示配色
            :params x_data:x轴需加载的数据
        """
        self.line.add_xaxis(xaxis_data=x_data)
        self.line.extend_axis(
            xaxis=opts.AxisOpts(
                # 类型，此处值一般代表时间，选择category
                type_="time",
                # 刻度参考线，非0起始，颜色白色
                axisline_opts=opts.AxisLineOpts(
                    is_on_zero=False, linestyle_opts=opts.LineStyleOpts(color="#ffffff1e")
                ),
                # 坐标轴指示器配置项
                axispointer_opts=opts.AxisPointerOpts(
                    is_show=True)
            ),
        )

    def set_y_xis(self, name:str, y_data: list):
        """
        添加Y轴数据，并配置Y轴显示配色
            :params name:系列名称
            :params y_data:系列加载的数据
        """
        self.line.add_yaxis(
            #  系列名称，用于 tooltip 的显示，legend 的图例筛选。
            series_name=name,
            y_axis=y_data,
            # 是否连接空数据，空数据使用 `None` 填充
            is_connect_nones= True,
            # 是否平滑曲线
            is_smooth=True,
            # 是否显示 symbol, 如果 false 则只有在 tooltip hover 的时候显示。
            is_symbol_show=True,
            # 标记的图形, 用于显示每个点的具体数值
            symbol="circle",
            # 标记的大小，可以设置成诸如 10 这样单一的数字，也可以用数组分开表示宽和高，
            # 例如 [20, 10] 表示标记宽为 20，高为 10。
            symbol_size=6,
            # 线样式配置项，采用theme主题后，无需额外设置
            # linestyle_opts=opts.LineStyleOpts(color="#00e600"),
            # label_opts=opts.LabelOpts(is_show=True, position="top", color="white"),
            # itemstyle_opts=opts.ItemStyleOpts(
            #     color="#00e600", border_color="#9dfc9e", border_width=3
            # ),
            # 提示框组件配置项
            tooltip_opts=opts.TooltipOpts(is_show=True),
            # 标记线配置项，
            markline_opts=opts.MarkLineOpts(data=[opts.MarkLineItem(type_="average")]),  # , linestyle_opts={"color":"#00e600"}),
            # 标记点配置项
            markpoint_opts=opts.MarkPointOpts(data=[opts.MarkPointItem(type_="min"),
                                                opts.MarkPointItem(type_="average"),
                                                opts.MarkPointItem(type_="max")],)
                                                # label_opts=opts.LabelOpts(position="inside", color="#ffffff", font_weight="700")),
    )

    def set_global_options(self, title:str, subtitle:str="", x_axis_name:str="时间"):
        """
        设置全局配置参数
            :params title:图表标题
             :params subtitle:图表副标题
            :params x_axis_name:x轴名称
        """
        self.line.set_global_opts(
            title_opts=opts.TitleOpts(
                # 主标题文本，支持使用 \n 换行
                title=title,
                # 副标题文本，支持使用 \n 换行
                subtitle=subtitle,
                # 主副标题之间的间距。
                item_gap= 10,
                # title组件离容器上侧的距离。
                pos_top="0",
                # 主标题字体样式配置项,白色，字体大小16
                title_textstyle_opts=opts.TextStyleOpts(color="#fff", font_size=14),
                # 副标题字体样式配置项
                subtitle_textstyle_opts=opts.TextStyleOpts(color="#fffff1f", font_size=11),
            ),
            legend_opts=opts.LegendOpts(
                # 图例的类型,普通图例。
                type_="plain",
                # 是否显示图例组件
                is_show=True,
                # 图例组件离容器上侧的距离。
                pos_top="top",
                # 图例列表的布局朝向,水平
                orient='horizontal',
                # 图例标记的图形高度
                item_height=20,
                # 图例每项之间的间隔
                item_gap=15,
                # 图例组件字体样式，白色，字体大小12
                textstyle_opts=opts.TextStyleOpts(color="#ffffff", font_size=12)
            ),
            xaxis_opts=opts.AxisOpts(
                # 坐标轴类型, 时间轴，适用于连续的时序数据，与数值轴相比时间轴带有时间的格式化，在刻度计算上也有所不同，
                type_="time",
                # 是否显示 x 轴。
                is_show=True,
                # 坐标轴两边留白策略，类目轴和非类目轴的设置和表现不一样。
                # 非类目轴，包括时间，数值，对数轴，boundaryGap是一个两个值的数组，分别表示数据最小值和最大值的延伸范围
                boundary_gap=False,
                # 坐标轴名称
                name=x_axis_name,
                # 坐标轴名称显示位置, 右侧
                name_location="end",
                # 坐标轴的分割段数，需要注意的是这个分割段数只是个预估值，最后实际显示的段数会在这个基础上根据分割后坐标轴刻度显示的易读程度作调整。
                # split_number=10,
                # 坐标轴名称的文字样式
                name_textstyle_opts={"color": '#ffffff'},
                # 坐标轴标签配置项, 白色，偏移30px
                axislabel_opts=opts.LabelOpts(margin=30, color="#ffffff", rotate=-5),
                # 坐标轴刻度线配置项
                axisline_opts=opts.AxisLineOpts(is_show=True),
                # 坐标轴刻度配置项
                axistick_opts=opts.AxisTickOpts(
                    is_show=True,
                    length=25,
                    linestyle_opts=opts.LineStyleOpts(color="#ffffff1f"),
                ),
                # 分割线配置项
                splitline_opts=opts.SplitLineOpts(
                    is_show=True, linestyle_opts=opts.LineStyleOpts(color="#ffffff1f")
                ),
            ),
            yaxis_opts=opts.AxisOpts(
                # 坐标轴类型,数值
                type_="value",
                # 坐标轴显示的位置
                position="left",
                # 坐标轴标签配置项, 白色，偏移20px
                axislabel_opts=opts.LabelOpts(margin=20, color="#ffffff"),
                # 坐标轴刻度线配置项
                axisline_opts=opts.AxisLineOpts(
                    linestyle_opts=opts.LineStyleOpts(width=2, color="#fff")
                ),
                # 坐标轴刻度配置项
                axistick_opts=opts.AxisTickOpts(
                    is_show=True,
                    length=15,
                    linestyle_opts=opts.LineStyleOpts(color="#ffffff1f"),
                ),
            ),
        )

    def save(self, name:str):
        """
        保存生成的图表
            :params name:图片名称
        """
        path = Path(f"{os.getcwd()}/pic")
        path.mkdir(parents=True, exist_ok=True)
        picture_path = f"{os.getcwd()}/pic/{name}.png"
        html_path = f"{os.getcwd()}/pic/{name}.html"
        self.files_path.extend([picture_path, html_path])
        try:
            make_snapshot(snapshot, self.line.render(html_path), picture_path)
        except Exception as error:
            logger.error(f"生成图片错误：{error}")
            return {}
        return {"html_path":html_path, "picture_path":picture_path}



class ItemAssign(EchartLine):
    def __init__(self, width:str='960px', height:str='540px', theme_name:str='DARK'):
        super().__init__(width, height, theme_name)



if __name__ == '__main__':
    line = EchartLine(theme_name="DARK")
    x_data = ["2020-03-29 10:00:12", "2020-03-29 10:00:13", "2020-03-29 10:00:14", "2020-03-29 10:00:15",
              "2020-03-29 10:00:16", "2020-03-29 10:00:17",
              "2020-03-29 10:00:18", "2020-03-29 10:00:19", "2020-03-29 10:00:20", "2020-03-29 10:00:21",
              "2020-03-29 10:00:22", "2020-03-29 10:00:23",
              "2020-03-29 10:00:24", "2020-03-29 10:00:25", "2020-03-29 10:00:26", "2020-03-29 10:00:27",
              "2020-03-29 10:00:28", "2020-03-29 10:00:29",
              "2020-03-29 10:00:30", "2020-03-29 10:00:31", "2020-03-29 10:00:32", "2020-03-29 10:00:33"]
    y_data = [15, 23, 34, 5, 56, 88, 3, 1, 2, 45, 62, 34,
              93, 48, 45, 31, 89, 84, 97, 10, 45, 10]

    y2_data = [51, 31, 34, 51, 56, 88, 21, 21, 41, 45, 62, 14,
               93, 48, 141, 21, 89, 84, 97, 100, 45, 20]

    line.set_x_xis(x_data)
    line.set_y_xis("dev", y_data)
    line.set_y_xis("trunk", y2_data)
    line.set_global_options("10.65.142.1 - TEST", "2020-03-29 10:00:12 ~ 2020-03-29 10:00:33")
    line.save("table")